
/**
\file Definition of nmn::math::constants
\author Sean Tromans
*/

#ifndef	NMN_TEMPLATES_MATH_CONSTANTS_HPP
#define	NMN_TEMPLATES_MATH_CONSTANTS_HPP

#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/is_arithmetic.hpp>

namespace nmn
{

	namespace math
	{

		/**
		Common mathmatical constants.
		\author Sean tromans
		*/
		template < typename TValueType >
		struct constants
		{
			/**
			Epsilon value to be used in equality checks on floating point values.
			\author Sean Tromans
			*/
			static TValueType epsilon( ) { return boost::numeric_cast< TValueType >( 0.00001 ); }

			/**
			The value of pi.
			\author Sean Tromans
			*/
			static TValueType pi( ) { return boost::numeric_cast< TValueType >( 3.14159265 ); }

			/**
			The value of pi / 2.
			\author Sean Tromans
			*/
			static TValueType pi_2( ) { return boost::numeric_cast< TValueType >( 1.57079633 ); }

			/**
			The value of pi / 4.
			\author Sean Tromans
			*/
			static TValueType pi_4( ) { return boost::numeric_cast< TValueType >( 0.785398163 ); }

			/**
			The value of pi * 2.
			\author Sean Tromans
			*/
			static TValueType two_pi( ) { return boost::numeric_cast< TValueType >( 6.28318531 ); }

			/**
			The value of e.
			\author Sean Tromans
			*/
			static TValueType e( ) { return boost::numeric_cast< TValueType >( 2.71828183 ); }

			/**
			The cosine of 45 degree or pi / 4 radians.
			\author Sean Tromans
			*/
			static TValueType cos_45( ) { return boost::numeric_cast< TValueType >( 0.707106781 ); }
			static TValueType cos_pi_4( ) { return cos_45( ); }

			/**
			The ratio to convert from degrees to radians.
			\author Sean Tromans
			*/
			static TValueType deg_to_rad_ratio( ) { return boost::numeric_cast< TValueType >( pi( ) / 180.0 ); }

			/**
			The ratio to convert from radians to degrees.
			\author Sean Tromans
			*/
			static TValueType rad_to_deg_ratio( ) { return boost::numeric_cast< TValueType >( 180.0 / pi( ) ); }

			private:
				constants() { }

				static_assert( boost::is_arithmetic< TValueType >::value, "TValueType must be a numeric value type." );
		};

		typedef constants<int>		constantsi;
		typedef constants<float>	constantsf;
		typedef constants<double>	constantsd;

	};

};

#endif	//NMN_TEMPLATES_MATH_CONSTANTS_HPP
